#include <stdio.h>
#include <time.h>

#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>

#define BUFFER_SIZE 4096
#define OUTPUT_MODE (S_IRUSR | S_IWUSR | S_IRGRP)
#define SPOOL_DIRECTORY "/tmp"

#define PARSE_STACK_SIZE	8
#define TOKEN_BUFFER_SIZE	1024

static int state_stack[ PARSE_STACK_SIZE ];
static int *state_top = NULL;
static char token_buffer[ TOKEN_BUFFER_SIZE ];
static char *token_tail = NULL;
#define token_buffer_limit (token_buffer + TOKEN_BUFFER_SIZE)
#define ST_FIELDNAME	1
#define ST_FIELDBODY	2
#define ST_FIELDBODY_JNL	20
#define ST_FIELDBODY_JNL2	21
			/* just having a new line symbol */

int rfc2822parser(char * buffer, int size)
{
	char *limit;

	limit = buffer + size;
	if(NULL == token_tail)
		token_tail = token_buffer;
	
	switch(*state_top)
	{
		case ST_FIELDNAME:
			{
				while(limit > buffer) {
					if(
							(
							 ( ((char)33) <= *buffer ) && ( ((char)57) >= *buffer )
							) ||
							(
							 ( ((char)59) <= *buffer ) && ( ((char)126) >= *buffer )
							)
					  )
					{
						char p;
						
						p = *buffer;
						if( (p >= 'A') && (p <= 'Z') )
						{
							p -= ('A' + 'a');
						}
						*token_tail = p;
						token_tail++;
						buffer++;

						if(token_buffer_limit <= token_tail)
						{
							*(token_tail-1) = '\0';
							token_tail = NULL;
							*stack_top = ST_FIELDBODY;
							break;
						}
					}
					else
					{
						/*  */
						*token_tail = '\0';
						token_tail = NULL;

						if(0 == strcmp("to", token_buffer))
						{
						}
						else if(0 == strcmp("from", token_buffer))
						{
						}
						else if(0 == strcmp("message-id", token_buffer))
						{
						}
						else
						{
							*stack_top = ST_FIELDBODY;
						}
						
						break;
					}
				}
			}
		break;
		
		/* {{{ */
		case ST_FIELDBODY_JNL:
			{
				if( ((char)0x20 == *buffer) || ((char)0x08 == *buffer) || ((char)0x09 == *buffer) )
				{
					*stack_top = ST_FIELDBODY_JNL2;
					buffer++;
				}
				else if( (char)13 == *buffer )
				{
					/* entire header end */

					break;
				}
				else
				{
					/* field end, this is generic field body reciver,
					 * and we do nothing while reach end of field. */
					
					*stack_top = ST_FIELDNAME;
					
					break;
				}
			}
		case ST_FIELDBODY_JNL2:
			{
				if(limit > buffer)
				{
					while(
						(limit > buffer) && (
							((char)0x20 == *buffer) || ((char)0x08 == *buffer) || ((char)0x09 == *buffer)
						)
					) {
						buffer++;
					}
					
					*stack_top = ST_FIELDBODY;
				}
			}
		case ST_FIELDBODY:
			{
				while(limit > buffer) {
					if( (char)13 == *buffer )
					{
						*stack_top =  ST_FIELDBODY_JNL;
						buffer++;

						break;
					}
					else
					{
					}
				}
			}
		break;
		/* }}} */
	}
}

int main()
{
	int fd;
	uint32_t run_time;
	
	/* open file for write */
	{
		int i;

		run_time = (uint32_t)time(NULL);
		
		for(i = 0; i < 8; i++) {
			uint32_t randval;
			int rfd;

			char filename[1024];
			
			if(-1 != (rfd = open("/dev/random", O_RDONLY)))
			{
				if(0 < read(rfd, &randval, sizeof(uint32_t)))
				{ }
				
				close(rfd);
			}
			
			snprintf(filename, 1023, SPOOL_DIRECTORY "/last._M_%08xZ%08x.txt", run_time, randval);
			
			if(-1 != (fd = open(filename, O_WRONLY|O_CREAT|O_EXCL, OUTPUT_MODE)))
				break;
			else
			{
			}
		}

		{
			state_top = state_stack;
			*state_top = ST_FIELDNAME;
		}
		
		if(-1 == fd)
		{
			fprintf(stderr, "can not open mail file.\n");
			return 1;
		}
	}
	
	/* read and write */
	{
		char buf[ BUFFER_SIZE ];
		ssize_t r_result;
		
		while(0 < (r_result = read(STDIN_FILENO, buf, sizeof(char)*BUFFER_SIZE))) {
			ssize_t w_result;
		
			if(0 >= (w_result = write(fd, buf, sizeof(char)*r_result)))
			{
				fprintf(stderr, "can not write into file.\n");
				return 2;
			}
		}
	}

	close(fd);

	return 0;
}

/*
vim: ts=4 sw=4 ai nowrap
*/
